﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dominio;

namespace Persistencia
{
    public class FachadaPersistencia: IPersistencia
    {
        private ConexionBD conn;

        #region constructor

        public FachadaPersistencia()
        {

            this.conn = ConexionBD.getInstance("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + Parameters.origenDatos);
        }

        #endregion

        #region properties

        public ConexionBD Conn
        {
            get { return conn; }
            set { conn = value; }
        }

        #endregion

        #region commonMethods

        //agrega el objeto a la base
        public void add(object o)
        {
            Broker br = Broker.crearBroker(o);
            br.add(o);
        }

        //modifica el objeto en la base
        public void update(object o)
        {
            Broker br = Broker.crearBroker(o);
            br.update(o);
        }

        //elimina un objeto de la base
        public void delete(object o)
        {
            Broker br = Broker.crearBroker(o);
            br.delete(o);
        }

        //recupera los datos del objeto de la base
        public void bringData(object o)
        {
            Broker br = Broker.crearBroker(o);
            br.bringData(o);
        }

        //obtiene todos los registros de una tabla
        public List<Object> bringList(object o)
        {
            Broker br = Broker.crearBroker(o);
            return br.bringList(o);
        }

        //obtiene el ultimo id de una tabla
        public int bringLastOID(object o)
        {
            Broker br = Broker.crearBroker(o);
            return br.bringLastId();
        }

        #endregion

        #region articulos

        public List<Articulo> traerArticulosNoHabilitados()
        {
            List<Articulo> lArticulos = new List<Articulo>();
            string sql = "select * from articulos where habilitado = false order by nombre";
            this.Conn.connect();
            this.Conn.bringList(sql);
            while (this.Conn.nextRecord())
            {
                Articulo articuloAux = new Articulo();
                articuloAux.Codigo = this.conn.getDataString("Codigo").ToString();
                articuloAux.Nombre = this.conn.getDataString("Nombre").ToString();
                articuloAux.Imagen = this.conn.getDataString("Imagen").ToString();
                articuloAux.Descripcion = this.conn.getDataString("Descripcion").ToString();
                articuloAux.FechaIngreso = (DateTime)this.conn.getDataString("FechaIngreso");
                articuloAux.Habilitado = (Boolean)this.conn.getDataString("Habilitado");
                articuloAux.Stock = int.Parse(this.conn.getDataString("Stock").ToString());
                articuloAux.IVA.OID = int.Parse(this.conn.getDataString("Iva").ToString());
                articuloAux.OID = int.Parse(this.conn.getDataString("IdArticulo").ToString());
                lArticulos.Add(articuloAux);
            }
            this.Conn.disconnect();
            return lArticulos;
        }

        public List<Articulo> buscarArticulos(int idDesde, int idHasta,
            string codigo, string nombre, int stockDesde, int stockHasta, int iva)
        {
            List<Articulo> lArticulos = new List<Articulo>();
            string sql = "select * from articulos where habilitado = true and idArticulo >= "
                + idDesde + " and idArticulo <= " + idHasta
                + " and stock >= " + stockDesde + " and stock <= " + stockHasta;
            if (!nombre.Equals(""))
            {
                sql += " and nombre like('%" + nombre + "%') ";
            }
            if (!codigo.Equals(""))
            {
                sql += " and codigo like('%" + codigo + "%')";
            }
            if (iva != -1)
            {
                sql += " and iva = " + iva;
            }
            sql += " order by nombre";
            this.Conn.connect();
            this.Conn.bringList(sql);
            while (this.Conn.nextRecord())
            {
                Articulo articuloAux = new Articulo();
                articuloAux.Codigo = this.conn.getDataString("Codigo").ToString();
                articuloAux.Nombre = this.conn.getDataString("Nombre").ToString();
                articuloAux.Imagen = this.conn.getDataString("Imagen").ToString();
                articuloAux.Descripcion = this.conn.getDataString("Descripcion").ToString();
                articuloAux.FechaIngreso = (DateTime)this.conn.getDataString("FechaIngreso");
                articuloAux.Habilitado = (Boolean)this.conn.getDataString("Habilitado");
                articuloAux.Stock = int.Parse(this.conn.getDataString("Stock").ToString());
                articuloAux.IVA.OID = int.Parse(this.conn.getDataString("Iva").ToString());
                articuloAux.OID = int.Parse(this.conn.getDataString("IdArticulo").ToString());
                lArticulos.Add(articuloAux);
            }
            this.Conn.disconnect();
            return lArticulos;
        }

        public Articulo buscarArticuloPorId(string id)
        {
            Articulo unArticulo = new Articulo();
            this.conn.connect();
            string sql = "select * from articulos "
                + "where idArticulo = " + id;
            this.Conn.bringData(sql);
            while (this.Conn.nextRecord())
            {
                unArticulo.OID = int.Parse(this.Conn.getDataString("IdArticulo").ToString());
                unArticulo.Codigo = this.Conn.getDataString("codigo").ToString();
                unArticulo.Nombre = this.Conn.getDataString("nombre").ToString();
                unArticulo.Imagen = this.Conn.getDataString("imagen").ToString();
                unArticulo.Descripcion = this.Conn.getDataString("descripcion").ToString();
                unArticulo.FechaIngreso = DateTime.Parse(this.Conn.getDataString("fechaIngreso").ToString());
                unArticulo.Habilitado = bool.Parse(this.Conn.getDataString("habilitado").ToString());
                unArticulo.Stock = int.Parse(this.Conn.getDataString("stock").ToString());
                unArticulo.IVA.OID = int.Parse(this.Conn.getDataString("iva").ToString());
            }
            return unArticulo;
        }

        public List<Articulo> listarArticulosPorFecha(DateTime unaF)
        {
            return null;
        }

        public List<Articulo> listarArticulosPorCodigo(string desde, string hasta)
        {
            return null;
        }

        public List<Articulo> listarArticuloPorStock(int desde, int hasta)
        {
            return null;
        }        

        #endregion

        #region clientes

        public List<Cliente> buscarClientes(string nombre, double saldoDesde, double saldoHasta,
            string rut, int numeroDesde, int numeroHasta, int idPlanDePago, string unaDireccion)
        {
            List<Cliente> lClientes = new List<Cliente>();
            int saldoDesdeEntero = (int)saldoDesde;
            int saldoDesdeDecimal = (int)((saldoDesde - saldoDesdeEntero) * 100);
            int saldoHastaEntero = (int)saldoHasta;
            int saldoHastaDecimal = (int)((saldoHasta - saldoHastaEntero) * 100);
            string sql = "select * from personas where EsCliente = true and habilitado = true and Saldo >= "
                + saldoDesdeEntero + "." + saldoDesdeDecimal
                + " and Saldo <= " + saldoHastaEntero + "." + saldoHastaDecimal
                + " and IdPersona >= " + numeroDesde + " and IdPersona <= " + numeroHasta;
            if (!nombre.Equals(""))
            {
                sql += " and Nombre like('%" + nombre + "%') ";
            }
            if (!rut.Equals(""))
            {
                sql += " and RUT like('%" + rut + "%')";
            }
            if (idPlanDePago != -1)
            {
                sql += " and IdPlan = " + idPlanDePago;
            }
            if (!unaDireccion.Equals(""))
            {
                sql += " and Direccion like('%" + unaDireccion + "%')";
            }
            sql += " order by Nombre";
            this.Conn.connect();
            this.Conn.bringList(sql);
            while (this.Conn.nextRecord())
            {
                Cliente clienteAux = new Cliente();
                clienteAux.Nombre = this.conn.getDataString("Nombre").ToString();
                clienteAux.Direccion = this.conn.getDataString("Direccion").ToString();
                clienteAux.PlanDePago.OID = int.Parse(this.conn.getDataString("IdPlan").ToString());
                clienteAux.Habilitado = (Boolean)this.conn.getDataString("Habilitado");
                clienteAux.Fax = int.Parse(this.conn.getDataString("Fax").ToString());
                clienteAux.EMail = this.conn.getDataString("EMail").ToString();
                clienteAux.Saldo = double.Parse(this.conn.getDataString("Saldo").ToString());
                clienteAux.OID = int.Parse(this.conn.getDataString("IdPersona").ToString());
                clienteAux.RUT = this.conn.getDataString("Rut").ToString();
                lClientes.Add(clienteAux);
            }
            this.Conn.disconnect();
            return lClientes;
        }

        public List<Cliente> traerClientesNoHabilitados()
        {
            List<Cliente> lClientes = new List<Cliente>();
            string sql = "select * from personas where Habilitado = false and esCliente = true order by nombre";
            this.Conn.connect();
            this.Conn.bringList(sql);
            while (this.Conn.nextRecord())
            {
                Cliente clienteAux = new Cliente();
                clienteAux.Nombre = this.conn.getDataString("Nombre").ToString();
                clienteAux.Direccion = this.conn.getDataString("Direccion").ToString();
                clienteAux.PlanDePago.OID = int.Parse(this.conn.getDataString("IdPlan").ToString());
                clienteAux.Habilitado = (Boolean)this.conn.getDataString("Habilitado");
                clienteAux.Fax = int.Parse(this.conn.getDataString("Fax").ToString());
                clienteAux.EMail = this.conn.getDataString("EMail").ToString();
                clienteAux.Saldo = double.Parse(this.conn.getDataString("Saldo").ToString());
                clienteAux.OID = int.Parse(this.conn.getDataString("IdPersona").ToString());
                clienteAux.RUT = this.conn.getDataString("Rut").ToString();
                lClientes.Add(clienteAux);
            }
            this.Conn.disconnect();
            return lClientes;
        }

        public Cliente buscarClientePorId(int id)
        {
            //this.conn.connect();
            //string sql = "select * from Clientes c, Personas p "
            //    + "where p.IdPersona = c.IdPersona "
            //    + "and p.IdPersona = " + id;
            //this.Conn.bringData(sql);
            return null;
        }

        public List<Cliente> listarClientesPorNumero(int desde, int hasta)
        {
            return null;
        }

        public List<Cliente> listarClientesPorNombre(string desde, string hasta)
        {
            return null;
        }

        #endregion

        #region proveedores

        public List<Proveedor> buscarProveedores(string nombre, double saldoDesde,
            double saldoHasta, string rut, int numeroDesde, int numeroHasta, int idPlanDePago,
            string unaDireccion)
        {
            List<Proveedor> lProveedores = new List<Proveedor>();
            int saldoDesdeEntero = (int)saldoDesde;
            int saldoDesdeDecimal = (int)((saldoDesde - saldoDesdeEntero) * 100);
            int saldoHastaEntero = (int)saldoHasta;
            int saldoHastaDecimal = (int)((saldoHasta - saldoHastaEntero) * 100);
            string sql = "select * from personas where EsCliente = false and habilitado = true and Saldo >= "
                + saldoDesdeEntero + "." + saldoDesdeDecimal
                + " and Saldo <= " + saldoHastaEntero + "." + saldoHastaDecimal
                + " and IdPersona >= " + numeroDesde + " and IdPersona <= " + numeroHasta;
            if (!nombre.Equals(""))
            {
                sql += " and Nombre like('%" + nombre + "%') ";
            }
            if (!rut.Equals(""))
            {
                sql += " and RUT like('%" + rut + "%')";
            }
            if (idPlanDePago != -1)
            {
                sql += " and IdPlan = " + idPlanDePago;
            }
            if (!unaDireccion.Equals(""))
            {
                sql += " and Direccion like('%" + unaDireccion + "%')";
            }
            sql += " order by Nombre";
            this.Conn.connect();
            this.Conn.bringList(sql);
            while (this.Conn.nextRecord())
            {
                Proveedor proveedorAux = new Proveedor();
                proveedorAux.Nombre = this.conn.getDataString("Nombre").ToString();
                proveedorAux.Direccion = this.conn.getDataString("Direccion").ToString();
                proveedorAux.PlanDePago.OID = int.Parse(this.conn.getDataString("IdPlan").ToString());
                proveedorAux.Habilitado = (Boolean)this.conn.getDataString("Habilitado");
                proveedorAux.Fax = int.Parse(this.conn.getDataString("Fax").ToString());
                proveedorAux.EMail = this.conn.getDataString("EMail").ToString();
                proveedorAux.Saldo = double.Parse(this.conn.getDataString("Saldo").ToString());
                proveedorAux.OID = int.Parse(this.conn.getDataString("IdPersona").ToString());
                proveedorAux.RUT = this.conn.getDataString("Rut").ToString();
                lProveedores.Add(proveedorAux);
            }
            this.Conn.disconnect();
            return lProveedores;
        }

        public List<Proveedor> traerProveedoresNoHabilitados()
        {
            List<Proveedor> lProveedores = new List<Proveedor>();
            string sql = "select * from personas where EsCliente = false and habilitado = false order by nombre";
            this.Conn.connect();
            this.Conn.bringList(sql);
            while (this.Conn.nextRecord())
            {
                Proveedor proveedorAux = new Proveedor();
                proveedorAux.Nombre = this.conn.getDataString("Nombre").ToString();
                proveedorAux.Direccion = this.conn.getDataString("Direccion").ToString();
                proveedorAux.PlanDePago.OID = int.Parse(this.conn.getDataString("IdPlan").ToString());
                proveedorAux.Habilitado = (Boolean)this.conn.getDataString("Habilitado");
                proveedorAux.Fax = int.Parse(this.conn.getDataString("Fax").ToString());
                proveedorAux.EMail = this.conn.getDataString("EMail").ToString();
                proveedorAux.Saldo = double.Parse(this.conn.getDataString("Saldo").ToString());
                proveedorAux.OID = int.Parse(this.conn.getDataString("IdPersona").ToString());
                proveedorAux.RUT = this.conn.getDataString("Rut").ToString();
                lProveedores.Add(proveedorAux);
            }
            this.Conn.disconnect();
            return lProveedores;
        }

        public Proveedor buscarProveedorPorId(int id)
        {
            return null;
        }

        #endregion

        #region searchMethods

        public FacturaCredito buscarFacturaCreditoPorId(int id)
        {
            return null;
        }

        //tener cuidado con el vencimiento para las facturas que ya estan pagas
        public List<FacturaCredito> listarFacturasPorVencimiento(DateTime desde, DateTime hasta)
        {
            return null;
        }


        //tener cuidado con el vencimiento para las facturas que ya estan pagas
        public List<FacturaProveedor> listarFacturasProvPorVencimiento(DateTime desde, DateTime hasta)
        {
            return null;
        }

        public NotaCredito buscarNotaCreditoPorId(int id)
        {
            return null;
        }

        public NotaDebito buscarNotaDebitoPorId(int id)
        {
            return null;
        }
        
        #endregion

        #region connectionMethods

        //conexion a la base
        public void connect(string cadena)
        {
            conn.connect();
        }

        //desconexion de la base
        public void disconnect()
        {
            conn.disconnect();
        }

        //establece string de conexion
        public void connectToDB()
        {
            this.conn = ConexionBD.getInstance("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" 
                + Parameters.origenDatos);
        }

        #endregion

    }
}
